package org.timemachine.generator;

import java.lang.reflect.Modifier;
import java.util.Locale;

import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.NotFoundException;

import org.timemachine.generator.spi.FieldGenerator;
import org.timemachine.model.base.ChangeInfo;

public class FieldGeneratorImpl implements FieldGenerator {

	public CtField createChangeInfoField(CtClass cc, String fieldName, String getterName, String setterName) throws NotFoundException, CannotCompileException {
		CtClass changeInfoClass = cc.getClassPool().get(ChangeInfo.class.getName());
		CtField changeField = new CtField(changeInfoClass, fieldName, cc);
		cc.addField(changeField);
		cc.addMethod(CtNewMethod.getter(getterName, changeField));
		cc.addMethod(CtNewMethod.setter(setterName, changeField));
		return changeField;
	}
	
	public CtField createChangeIdField(CtClass cc) throws CannotCompileException {
		CtField changeIdField = new CtField(CtClass.intType, "changeId", cc);
		cc.addField(changeIdField);
		cc.addMethod(CtNewMethod.getter("getChangeId", changeIdField));
		cc.addMethod(CtNewMethod.setter("setChangeId", changeIdField));
		return changeIdField;
	}
	
	public void createFieldWithGetterSetter(CtClass cc, CtField ctField) throws CannotCompileException, NotFoundException {
		CtField newField = new CtField(ctField.getType(), ctField.getName(), cc);
		newField.setModifiers(Modifier.PRIVATE);
		cc.addField(newField);
		cc.addMethod(CtNewMethod.getter(getGetterName(ctField.getName()), ctField));
		cc.addMethod(CtNewMethod.setter(getSetterName(ctField.getName()), ctField));
	}
	
	public void removeSetter(CtClass cc, CtField ctField)	throws NotFoundException {
		CtMethod setterMethod = cc.getDeclaredMethod(getSetterName(ctField.getName()));
		if (setterMethod != null) {
			cc.removeMethod(setterMethod);					
		}
	}

	public void removeGetter(CtClass cc, CtField ctField)	throws NotFoundException {
		CtMethod getterMethod = cc.getDeclaredMethod(getGetterName(ctField.getName()));
		if (getterMethod != null) {
			cc.removeMethod(getterMethod);					
		}
	}

	public String getGetterName(String fieldName) {
		return "get" + fieldName.substring(0, 1).toUpperCase(new Locale("en")) + fieldName.substring(1);
	}

	public String getSetterName(String fieldName) {
		return "set" + fieldName.substring(0, 1).toUpperCase(new Locale("en")) + fieldName.substring(1);
	}

}
